package game.cube;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

public class Cube implements Shape{
	private static final int SHORT_SIZE_BYTES	= 2;
	private static final int FLOAT_SIZE_BYTES	= 4;

	public static  float SIZE			= 1.00f;
	public static  float SIZE_X			= 1.00f;
	public static  float SIZE_Y			= 1.00f;
	public static  float SIZE_Z			= 1.00f;

	private float[] mVertex = {
		 SIZE_X,  SIZE_Y,  SIZE_Z,
		-SIZE_X,  SIZE_Y,  SIZE_Z,
		-SIZE_X, -SIZE_Y,  SIZE_Z,
		 SIZE_X, -SIZE_Y,  SIZE_Z,
		 SIZE_X,  SIZE_Y, -SIZE_Z,
		-SIZE_X,  SIZE_Y, -SIZE_Z,
		-SIZE_X, -SIZE_Y, -SIZE_Z,
		 SIZE_X, -SIZE_Y, -SIZE_Z,
	};

	private short[] mIndex = {
		0, 4, 7,
		0, 7, 3,
		1, 5, 6,
		1, 6, 2,
		0, 1, 5,
		0, 5, 4,
		3, 2, 6,
		3, 6, 7,
		0, 1, 2,
		0, 2, 3,
		4, 5, 6,
		4, 6, 7
	};

	private float[] mColor = {
		0.0f, 1.0f, 0.0f, 1.0f,
		0.0f, 1.0f, 0.0f, 1.0f,
		0.0f, 1.0f, 0.0f, 1.0f,
		0.0f, 1.0f, 0.0f, 1.0f,
		0.0f, 1.0f, 0.0f, 1.0f,
		0.0f, 1.0f, 0.0f, 1.0f,
		0.0f, 1.0f, 0.0f, 1.0f,
		0.0f, 1.0f, 0.0f, 1.0f,
	};

	private FloatBuffer mVertexBuffer;
	private FloatBuffer  mColorBuffer;
	private ShortBuffer  mIndexBuffer;

	private Matrix mParentTranslateMatrix = new Matrix();
	private Matrix		 mTranslateMatrix = new Matrix();
	private Matrix		    mRotateMatrix = new Matrix();
	private Matrix			 mMixedMatrix = new Matrix();

	private boolean mActive;
	private boolean mSearchedFlag;
	public boolean	mRotateFlagX				= false;
	public boolean	mRotateFlagY				= false;
	public boolean	mRotateFlagZ				= false;
	public boolean	mRrotateTranslateFlag	= false;
	public int		mMoveState	= 0;

	public Cube() {
		mVertexBuffer = ByteBuffer.allocateDirect(mVertex.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
		mVertexBuffer.put(mVertex).position(0);

		mIndexBuffer = ByteBuffer.allocateDirect(mIndex.length * SHORT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asShortBuffer();
		mIndexBuffer.put(mIndex).position(0);

		mColorBuffer = ByteBuffer.allocateDirect(mColor.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
		mColorBuffer.put(mColor).position(0);
	}

	public void set_proper_position() {
		float size = SIZE * 2;
		for (float proper_position = -size; proper_position <= size; proper_position += size) {
			if (mMixedMatrix.m[12] < proper_position + SIZE_X && mMixedMatrix.m[12] > proper_position - SIZE_X) {
				mMixedMatrix.m[12] = proper_position;
			}
			if (mMixedMatrix.m[13] < proper_position + SIZE_Y && mMixedMatrix.m[13] > proper_position - SIZE_Y) {
				mMixedMatrix.m[13] = proper_position;
			}
			if (mMixedMatrix.m[14] < proper_position + SIZE_Z && mMixedMatrix.m[14] > proper_position - SIZE_Z) {
				mMixedMatrix.m[14] = proper_position;
			}
		}
	}

	public void set_proper_position_x(float proper_position) {
		if (mMixedMatrix.m[12] < proper_position + SIZE_X && mMixedMatrix.m[12] > proper_position - SIZE_X) {
			mMixedMatrix.m[12] = proper_position;
		}
	}
	public void set_proper_position_y(float proper_position) {
		if (mMixedMatrix.m[13] < proper_position + SIZE_Y && mMixedMatrix.m[13] > proper_position - SIZE_Y) {
			mMixedMatrix.m[13] = proper_position;
		}
	}
	public void set_proper_position_z(float proper_position) {
		if (mMixedMatrix.m[14] < proper_position + SIZE_Z && mMixedMatrix.m[14] > proper_position - SIZE_Z) {
			mMixedMatrix.m[14] = proper_position;
		}
	}
	
	public float get_position_x() {
		return mMixedMatrix.m[12];
	}
	public float get_position_y() {
		return mMixedMatrix.m[13];
	}
	public float get_position_z() {
		return mMixedMatrix.m[14];
	}

	public float[] get_color() {
		return mColor;
	}
	public void set_color(float[] color) {
		for (int i = 0; i < mColor.length; i += 4) {
			mColor[i + 0] = color[0];
			mColor[i + 1] = color[1];
			mColor[i + 2] = color[2];
			mColor[i + 3] = color[3];
		}
		mColorBuffer = ByteBuffer.allocateDirect(mColor.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
		mColorBuffer.put(mColor).position(0);

	}
	public void set_alpha(float alpha) {
		for (int i = 0; i < mColor.length; i += 4) {
			mColor[i + 3] = alpha;
		}
		mColorBuffer = ByteBuffer.allocateDirect(mColor.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
		mColorBuffer.put(mColor).position(0);
	}

	public void set_size(float size_x, float size_y, float size_z) {
		SIZE_X = size_x;
		SIZE_Y = size_y;
		SIZE_Z = size_z;

		mVertex[0] =   SIZE_X; mVertex[1]  =  SIZE_Y; mVertex[2] = SIZE_Z;
		mVertex[3] =  -SIZE_X; mVertex[4]  =  SIZE_Y; mVertex[5] = SIZE_Z;
		mVertex[6] =  -SIZE_X; mVertex[7]  = -SIZE_Y; mVertex[8] = SIZE_Z;
		mVertex[9] =   SIZE_X; mVertex[10] = -SIZE_Y; mVertex[11] = SIZE_Z;
		mVertex[12] =  SIZE_X; mVertex[13] =  SIZE_Y; mVertex[14] = -SIZE_Z;
		mVertex[15] = -SIZE_X; mVertex[16] =  SIZE_Y; mVertex[17] = -SIZE_Z;
		mVertex[18] = -SIZE_X; mVertex[19] = -SIZE_Y; mVertex[20] = -SIZE_Z;
		mVertex[21] =  SIZE_X; mVertex[22] = -SIZE_Y; mVertex[23] = -SIZE_Z;

		mVertexBuffer = ByteBuffer.allocateDirect(mVertex.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
		mVertexBuffer.put(mVertex).position(0);
	}

	public boolean is_same_color(float[] color) {
		if (mColor[0] == color[0] &&
			mColor[1] == color[1] &&
			mColor[2] == color[2]) {
			return true;
		}
		return false;
	}

	public void set_active(boolean flag) {
		mActive = flag;
	}

	public boolean is_active() {
		return mActive;
	}

	public void set_searched(boolean flag) {
		mSearchedFlag = flag;
	}

	public boolean is_searched() {
		return mSearchedFlag;
	}

	public void setTranslate(float x, float y, float z) {
		mTranslateMatrix.set_translate(x, y, z);
	}
	public void add_translation(float x, float y, float z) {
		mTranslateMatrix.add_translate(x, y, z);
	}
	public float get_translation_y() {
		return mTranslateMatrix.m[7];
	}

	public void setParentTranslate(float x, float y, float z) {
		mParentTranslateMatrix.set_translate(x, y, z);
	}
	public void add_parent_translation(float x, float y, float z) {
		mParentTranslateMatrix.add_translate(x, y, z);
	}

	public void setAngleX(float angle) {mRotateMatrix.mAngleX = angle;}
	public void setAngleY(float angle) {mRotateMatrix.mAngleY = angle;}
	public void setAngleZ(float angle) {mRotateMatrix.mAngleZ = angle;}
	public float getAngleX() {return mRotateMatrix.mAngleX;}
	public float getAngleY() {return mRotateMatrix.mAngleY;}
	public float getAngleZ() {return mRotateMatrix.mAngleZ;}
	public void setRotateX(float angle) {mRotateMatrix.set_rotate_x(angle);}
	public void setRotateY(float angle) {mRotateMatrix.set_rotate_y(angle);}
	public void setRotateZ(float angle) {mRotateMatrix.set_rotate_z(angle);}
	public void addRotateX(float angle) {mRotateMatrix.add_rotate_x(angle);}
	public void addRotateY(float angle) {mRotateMatrix.add_rotate_y(angle);}
	public void addRotateZ(float angle) {mRotateMatrix.add_rotate_z(angle);}
	public void mixParentTranslate() {
		mMixedMatrix.m[13] += mParentTranslateMatrix.m[7];
	}
	public void mixTranslate() {
		mMixedMatrix.m[13] = mTranslateMatrix.m[7];
	}
	public void mixTranslateToRotateMatrix() {
		mMixedMatrix = mTranslateMatrix.multiple_matrix(mRotateMatrix);
	}
	public void mixRotateToTranslateMatrix() {
		mMixedMatrix =  mRotateMatrix.multiple_matrix(mTranslateMatrix);
	}
	public void setTranslateForMixed() {
		mRotateMatrix.identity();
		mRotateMatrix.mAngleX = 0.0f;
		mRotateMatrix.mAngleY = 0.0f;
		mRotateMatrix.mAngleZ = 0.0f;

		mTranslateMatrix.identity();
		mTranslateMatrix.set_translate(mMixedMatrix.m[12], mMixedMatrix.m[13], mMixedMatrix.m[14]);
//		mTranslateMatrix.set_inverse_translate(mMixedMatrix.m[3], mMixedMatrix.m[7], mMixedMatrix.m[11]);

	}
	public void identityTranslate() {
		mTranslateMatrix.identity();
	}
	public void identityRotate() {
		mRotateMatrix.identity();
		mRotateMatrix.mAngleX = 0.0f;
		mRotateMatrix.mAngleY = 0.0f;
		mRotateMatrix.mAngleZ = 0.0f;
	}
	public void saveTranslate() {
		Matrix m = new Matrix();
		m.identity();
		mParentTranslateMatrix =mTranslateMatrix;// m.multiple_matrix(mTranslateMatrix);
	}
	public void loadTranslate() {
		for (int i = 0; i < 16; ++i) {
			mTranslateMatrix.m[i] = mParentTranslateMatrix.m[i];
		}
	}
	public FloatBuffer getVertexBuffer() { return mVertexBuffer; }
	public ShortBuffer getIndexBuffer()  { return mIndexBuffer;  }
	public FloatBuffer getColorBuffer()  { return mColorBuffer;  }
	public int         getIndexLength()  { return mIndex.length; }
	public float[]     getMatrix()       { return mMixedMatrix.m;}
}
